/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package stud.cp.user.plugins.designer;

import java.util.List;
import org.apache.log4j.*;
import javax.ejb.Stateless;
import javax.servlet.http.HttpServletRequest;
import stud.cp.core.dbaccess.DAOException;
import stud.cp.core.plugins.PluginConst;
import stud.cp.core.plugins.PluginRouter;
import stud.cp.core.plugins.WrongPageRequest;
import stud.cp.user.dbaccess.OracleDAOFactory;
import stud.cp.user.dbaccess.PropertyValueDAO;
import stud.cp.user.dbaccess.WeaponTypesPropertiesDAO;
import stud.cp.user.valueobjects.Property;
import stud.cp.user.valueobjects.PropertyValue;
import stud.cp.user.valueobjects.Weapon;
import stud.cp.user.valueobjects.WeaponType;
import stud.cp.user.valueobjects.WeaponTypesProperties;

/**
 * Класс - плагин, отвечающий за конструктор типов оружия.
 * @author Morfant
 */
@Stateless
public class WeaponTypePluginBean implements WeaponTypePluginLocal {

    /**
     * Фабрика DAO классов.
     */
    private OracleDAOFactory oracleDAOFactory = null;
    /**
     * Логгер.
     */
    private static Logger logger = Logger.getLogger("CPTNP");

    /**
     * Метод, инициализирущий фабрику DAO.
     */
    /**
     * Метод, выполняющий бизнес логику плагина.
     * @param req Реквест.
     * @return Класс плагин.
     */
    @Override
    public PluginRouter perform(HttpServletRequest req) {
        String subaction = req.getParameter(PluginConst.SUBACTION);

        if ((subaction != null) && (!subaction.equals(""))) {
            try {

                oracleDAOFactory = new OracleDAOFactory();
                oracleDAOFactory.initialize();
                /* Список действий которые могут выполниться. */

                if (subaction.equals(PluginConst.GET_LIST)) {/*Список данных*/
                    return getListPage(req);
                }

                /*Страница добавления*/
                if (subaction.equals(PluginConst.GET_ADD_PAGE)) {
                    return getAddPage(req);
                }

                /*Добавление новых данных*/
                if (subaction.equals(PluginConst.NEW_DATA)) {
                    return newData(req);
                }

                /*Страница редактирования*/
                if (subaction.equals(PluginConst.GET_EDIT_PAGE)) {
                    return getEditPage(req);
                }

                /*Сохранение измененных данных*/
                if (subaction.equals(PluginConst.SAVE_DATA)) {
                    return saveData(req);
                }

                /*Страница удаления*/
                if (subaction.equals(PluginConst.GET_DELETE_PAGE)) {
                    return getDeletePage(req);
                }

                /*Удаление данные*/
                if (subaction.equals(PluginConst.DELETE_DATA)) {
                    return deleteData(req);
                }

                /*Страница просмотра данных о типе оружия*/
                if (subaction.equals(PluginConst.GET_VIEW_PAGE)) {
                    return getViewPage(req);
                }

                /*Страница со списком свойств, принадлежащий данному типу оружия.*/
                if (subaction.equals(PluginConst.GET_WEAPON_TYPE_PROPERTIES_LIST)) {
                    return getWeaponTypePropertyListPage(req);
                }

                /*Страница с диалогом для пользователя, который хочет исключить свойство из типа оружия.*/
                if (subaction.equals(PluginConst.EXCLUDE_PROPERTY_FROM_WEAPON_TYPE_PAGE)) {
                    return getExcludePropertyFromWeaponTypePage(req);
                }

                /*Исключение свойства из объектного типа.*/
                if (subaction.equals(PluginConst.EXCLUDE_PROPERTY_FROM_WEAPON_TYPE)) {
                    return excludePropertyFromWeaponType(req);
                }

                /*Страница добавления свойств к типу оружия.*/
                if (subaction.equals(PluginConst.ADD_PROPERTIES_TO_WEAPON_TYPE_PAGE)) {
                    return getAddPropertiesToWeaponTypePage(req);
                }

                /*Добавление свойств к объектному типу*/
                if (subaction.equals(PluginConst.ADD_PROPERTIES_TO_WEAPON_TYPE)) {
                    return addPropertiesToWeaponType(req);
                }

                req.setAttribute(PluginConst.ERROR_MESSAGE,
                        "Действия для данного типа поддействия не найдено. Тип поддействия = " + subaction);
            } catch (DAOException ex) {
                logger.debug("Error due access to database. "
                        + "Plugin = WeaponTypePluginBean. "
                        + "Subaction=" + subaction, ex);
                req.setAttribute(PluginConst.ERROR_MESSAGE,
                        "Ошибка доступа к базе данных " + ex.getMessage());
            } catch (WrongPageRequest ex) {
                req.setAttribute(PluginConst.ERROR_MESSAGE,
                        "Данные из реквеста ошибочны :\n" + ex.getMessage());
            } finally {
                if (oracleDAOFactory != null) {
                    try {
                        oracleDAOFactory.cleanUp();
                    } catch (DAOException ex) {
                        logger.debug("Error due access to database. "
                                + "Plugin = WeaponTypePluginBean. "
                                + "Subaction=" + subaction, ex);
                        req.setAttribute(PluginConst.ERROR_MESSAGE,
                                "Ошибка доступа к базе данных " + ex.getMessage());
                    }
                }
            }
        } else {
            req.setAttribute(PluginConst.ERROR_MESSAGE,
                    "Тип поддействия не задан.");
        }

        return new PluginRouter("/errorpage.jsp");
    }

    /**
     * Метод, который позволяет получить
     * список данных запрашиваемого типа.
     * @param req Реквест.
     * @return PluginRouter на страницу в который будет выводиться список.
     * @throws DAOException Ошибки доступа к базе данных.
     */
    private PluginRouter getListPage(HttpServletRequest req) throws DAOException {
        req.setAttribute(PluginConst.WEAPON_TYPES_LIST, oracleDAOFactory.getWeaponTypesDAO().getAll());
        return new PluginRouter("/Designer/WeaponType/WeaponTypesTable.jsp");
    }

    /**
     * Метод, который позволяет получить
     * страницу добавления.
     * @param req Реквест.
     * @return PluginRouter c запрашиваемой страницей.
     * @throws DAOException Ошибка доступа к базе данных.
     */
    private PluginRouter getAddPage(HttpServletRequest req) throws DAOException {
        return new PluginRouter("/Designer/WeaponType/AddWeaponType.jsp");
    }

    /**
     * Метод, позволяющий добавлять новые данные.
     * @param req Реквест.
     * @return PluginRouter c запрашиваемой страницей.
     * @throws DAOException Ошибка доступа к базе данных.
     * @throws WrongPageRequest Критическая ошибка в данных реквеста.
     */
    private PluginRouter newData(HttpServletRequest req) throws DAOException, WrongPageRequest {
        String name = req.getParameter(PluginConst.WEAPON_TYPE_NAME);
        String description = req.getParameter(PluginConst.WEAPON_TYPE_DESCRIPTION);
        String error_message = "";
        if ((name == null) || (name.equals(""))) {
            error_message = error_message + "Имя типа оружия не должно быть пустым!";
        }
        if ((description == null) || (description.equals(""))) {
            error_message = error_message + " Описание типа оружия не должно быть пустым.";
        }
        if (error_message.equals("")) {
            int weapon_type_id = oracleDAOFactory.getWeaponTypesDAO().
                    create(new WeaponType(name, description));
            return new PluginRouter("weapon-type-action.do"
                    + "?"
                    + PluginConst.SUBACTION
                    + "="
                    + PluginConst.GET_VIEW_PAGE
                    + "&"
                    + PluginConst.WEAPON_TYPE_ID
                    + "="
                    + weapon_type_id, false);
        } else {
            req.setAttribute(PluginConst.ERROR_MESSAGE, error_message);
            return getAddPage(req);
        }
    }

    /**
     * Метод, который позволяет
     * перейти на страницу удаления элемента.
     * @param req Реквест.
     * @return PluginRouter c запрашиваемой страницей.
     * @throws DAOException Ошибка доступа к базе данных.
     * @throws WrongPageRequest Критическая ошибка в данных реквеста.
     */
    private PluginRouter getDeletePage(HttpServletRequest req) throws DAOException, WrongPageRequest {
        String weapon_type_id = req.getParameter(PluginConst.WEAPON_TYPE_ID);
        if (weapon_type_id != null) {
            WeaponType weaponType = oracleDAOFactory.getWeaponTypesDAO().getById(new Integer(weapon_type_id));
            if (weaponType != null) {
                req.setAttribute(PluginConst.WEAPON_TYPE, weaponType);
                return new PluginRouter("/Designer/WeaponType/DeleteWeaponType.jsp");
            } else {
                throw new WrongPageRequest("Тип оружия с таким id=" + weapon_type_id + " не существует. ");
            }
        } else {
            throw new WrongPageRequest("ID типа оружия не заданно.");
        }
    }

    /**
     * Метод, удаляющий данные из базы данных.
     * @param req Реквест.
     * @return PluginRouter c запрашиваемой страницей.
     * @throws DAOException Ошибка доступа к базе данных.
     * @throws WrongPageRequest Критическая ошибка в данных реквеста.
     */
    private PluginRouter deleteData(HttpServletRequest req) throws DAOException, WrongPageRequest {
        String weapon_type_id = req.getParameter(PluginConst.WEAPON_TYPE_ID);
        if (weapon_type_id != null) {
            WeaponType weaponType = oracleDAOFactory.getWeaponTypesDAO().getById(new Integer(weapon_type_id));
            if (weaponType != null) {
                oracleDAOFactory.getWeaponTypesDAO().delete(weaponType.getWeapon_type_id());
                return new PluginRouter("weapon-type-action.do"
                        + "?"
                        + PluginConst.SUBACTION
                        + "="
                        + PluginConst.GET_LIST, false);
            } else {
                throw new WrongPageRequest("Тип оружия с таким id=" + weapon_type_id + " не существует. ");
            }
        } else {
            throw new WrongPageRequest("ID типа оружия не задано.");
        }
    }

    /**
     * Метод, который позволяет
     * перейти на страницу просмотра данных о элементе.
     * @param req Реквест.
     * @return PluginRouter c запрашиваемой страницей.
     * @throws DAOException Ошибка доступа к базе данных.
     * @throws WrongPageRequest Критическая ошибка в данных реквеста.
     */
    private PluginRouter getViewPage(HttpServletRequest req) throws DAOException, WrongPageRequest {
        String weapon_type_id = req.getParameter(PluginConst.WEAPON_TYPE_ID);
        if (weapon_type_id != null) {
            WeaponType weaponType = oracleDAOFactory.getWeaponTypesDAO().getById(new Integer(weapon_type_id));
            if (weaponType != null) {
                req.setAttribute(PluginConst.WEAPON_TYPE, weaponType);
                return new PluginRouter("/Designer/WeaponType/ViewWeaponType.jsp");
            } else {
                throw new WrongPageRequest("Тип оружия с таким id=" + weapon_type_id + " не существует. ");
            }
        } else {
            throw new WrongPageRequest("ID типа оружия не заданно.");
        }
    }

    /**
     * Метод, который позволяет
     * перейти на страницу редактирования данных.
     * @param req Реквест.
     * @return PluginRouter c запрашиваемой страницей.
     * @throws DAOException Ошибка доступа к базе данных.
     * @throws WrongPageRequest Критическая ошибка в данных реквеста.
     */
    private PluginRouter getEditPage(HttpServletRequest req) throws DAOException, WrongPageRequest {
        String weapon_type_id = req.getParameter(PluginConst.WEAPON_TYPE_ID);
        if (weapon_type_id != null) {
            WeaponType weaponType = oracleDAOFactory.getWeaponTypesDAO().getById(new Integer(weapon_type_id));
            if (weaponType != null) {
                req.setAttribute(PluginConst.WEAPON_TYPE, weaponType);
                return new PluginRouter("/Designer/WeaponType/EditWeaponType.jsp");
            } else {
                throw new WrongPageRequest("Тип оружия с таким id=" + weapon_type_id + " не существует. ");
            }
        } else {
            throw new WrongPageRequest("ID типа оружия не заданно.");
        }
    }

    /**
     * Сохранение данных.
     * @param req Реквест.
     * @return PluginRouter c запрашиваемой страницей.
     * @throws DAOException Ошибка доступа к базе данных.
     * @throws WrongPageRequest Критическая ошибка в данных реквеста.
     */
    private PluginRouter saveData(HttpServletRequest req) throws DAOException, WrongPageRequest {
        String name = req.getParameter(PluginConst.WEAPON_TYPE_NAME);
        String description = req.getParameter(PluginConst.WEAPON_TYPE_DESCRIPTION);
        String weapon_type_id = req.getParameter(PluginConst.WEAPON_TYPE_ID);
        String error_message = "";
        if ((name == null) || (name.equals(""))) {
            error_message = error_message + "Имя типа оружия не должно быть пустым!";
        }
        if ((description == null) || (description.equals(""))) {
            error_message = error_message + " Описание типа оружия не должно быть пустым.";
        }
        if (weapon_type_id == null) {
            throw new WrongPageRequest("ID типа оружия не заданно.");
        }

        if (error_message.equals("")) {
            WeaponType weaponType = oracleDAOFactory.getWeaponTypesDAO().getById(new Integer(weapon_type_id));
            if (weaponType != null) {
                weaponType.setName(name);
                weaponType.setDescription(description);
                oracleDAOFactory.getWeaponTypesDAO().
                        update(weaponType);
                return new PluginRouter("weapon-type-action.do"
                        + "?"
                        + PluginConst.SUBACTION
                        + "="
                        + PluginConst.GET_VIEW_PAGE
                        + "&"
                        + PluginConst.WEAPON_TYPE_ID
                        + "="
                        + weapon_type_id, false);
            } else {
                throw new WrongPageRequest("Тип оружия с таким id=" + weapon_type_id + " не существует. ");
            }
        } else {
            req.setAttribute(PluginConst.ERROR_MESSAGE, error_message);
            return getEditPage(req);
        }
    }

    /**
     * Метод, позволяющий получить список
     * свойств, принадлежащий типу оружия.
     * @param req Реквест.
     * @return PluginRouter c запрашиваемой страницей.
     * @throws DAOException Ошибка доступа к базе данных.
     * @throws WrongPageRequest Критическая ошибка в данных реквеста.
     */
    private PluginRouter getWeaponTypePropertyListPage(HttpServletRequest req) throws DAOException, WrongPageRequest {
        String weapon_type_id = req.getParameter(PluginConst.WEAPON_TYPE_ID);
        if (weapon_type_id != null) {
            WeaponType weaponType = oracleDAOFactory.getWeaponTypesDAO().getById(new Integer(weapon_type_id));
            if (weaponType != null) {
                req.setAttribute(PluginConst.PROPERTIES_LIST,
                        oracleDAOFactory.getPropertiesDAO().getAllPropertyForWeaponType(weaponType.getWeapon_type_id()));
                req.setAttribute(PluginConst.WEAPON_TYPE_ID, weaponType.getWeapon_type_id());
                return new PluginRouter("/Designer/WeaponType/IncludingPropertiesTable.jsp");
            } else {
                throw new WrongPageRequest("Тип оружия с таким id=" + weapon_type_id + " не существует. ");
            }
        } else {
            throw new WrongPageRequest("ID типа оружия не заданно.");
        }
    }

    /**
     * Метод, позволяющий получить список
     * свойств, принадлежащий типу оружия.
     * @param req Реквест.
     * @return PluginRouter c запрашиваемой страницей.
     * @throws DAOException Ошибка доступа к базе данных.
     * @throws WrongPageRequest Критическая ошибка в данных реквеста.
     */
    private PluginRouter getExcludePropertyFromWeaponTypePage(HttpServletRequest req) throws DAOException, WrongPageRequest {
        String propety_id = req.getParameter(PluginConst.PROPERTY_ID);
        String weapon_type_id = req.getParameter(PluginConst.WEAPON_TYPE_ID);
        String error_message = "";
        if (weapon_type_id == null) {
            error_message = "ID типа оружия не задан.";
        }
        if (propety_id == null) {
            error_message = error_message + " ID свойства не задан.";
        }
        if (error_message.equals("")) {
            WeaponType weaponType = oracleDAOFactory.getWeaponTypesDAO().getById(new Integer(weapon_type_id));
            if (weaponType != null) {
                Property property = oracleDAOFactory.getPropertiesDAO().getById(new Integer(propety_id));
                req.setAttribute(PluginConst.WEAPON_TYPE_ID, weaponType.getWeapon_type_id());
                req.setAttribute(PluginConst.PROPERTY, property);
                return new PluginRouter("/Designer/WeaponType/ExcludeProperty.jsp");
            } else {
                throw new WrongPageRequest("Тип оружия с таким id=" + weapon_type_id + " не существует. ");
            }
        } else {
            throw new WrongPageRequest(error_message);
        }
    }

    /**
     * Метод, который исключает свойство
     * из типа оружия.
     * @param req Реквест.
     * @return PluginRouter c запрашиваемой страницей.
     * @throws DAOException Ошибка доступа к базе данных.
     * @throws WrongPageRequest Критическая ошибка в данных реквеста.
     */
    private PluginRouter excludePropertyFromWeaponType(HttpServletRequest req) throws DAOException, WrongPageRequest {
        String propety_id = req.getParameter(PluginConst.PROPERTY_ID);
        String weapon_type_id = req.getParameter(PluginConst.WEAPON_TYPE_ID);
        String error_message = "";
        if (weapon_type_id == null) {
            error_message = "ID типа оружия не задан.";
        }
        if (propety_id == null) {
            error_message = error_message + " ID свойства не задан.";
        }
        if (error_message.equals("")) {
            WeaponType weaponType = oracleDAOFactory.getWeaponTypesDAO().getById(new Integer(weapon_type_id));
            if (weaponType != null) {
                oracleDAOFactory.getWeaponTypesPropertiesDAO().
                        deleteForAppropriatePropertyIDAndWeaponTypeID(new Integer(propety_id), weaponType.getWeapon_type_id());
                return new PluginRouter("weapon-type-action.do"
                        + "?"
                        + PluginConst.SUBACTION
                        + "="
                        + PluginConst.GET_WEAPON_TYPE_PROPERTIES_LIST
                        + "&"
                        + PluginConst.WEAPON_TYPE_ID
                        + "="
                        + weapon_type_id, false);
            } else {
                throw new WrongPageRequest("Тип оружия с таким id=" + weapon_type_id + " не существует. ");
            }
        } else {
            throw new WrongPageRequest(error_message);
        }
    }

    /**
     * Метод, переводящий на страницу
     * добавления свойств к типу оружия.
     * @param req Реквест.
     * @return PluginRouter c запрашиваемой страницей.
     * @throws DAOException Ошибка доступа к базе данных.
     * @throws WrongPageRequest Критическая ошибка в данных реквеста.
     */
    private PluginRouter getAddPropertiesToWeaponTypePage(HttpServletRequest req) throws DAOException, WrongPageRequest {
        String weapon_type_id = req.getParameter(PluginConst.WEAPON_TYPE_ID);
        if (weapon_type_id != null) {
            WeaponType weaponType = oracleDAOFactory.getWeaponTypesDAO().getById(new Integer(weapon_type_id));
            if (weaponType != null) {
                req.setAttribute(PluginConst.PROPERTIES_LIST,
                        oracleDAOFactory.getPropertiesDAO().
                        getAllPropertiesThatNotBelongToWeaponType(weaponType.getWeapon_type_id()));
                req.setAttribute(PluginConst.WEAPON_TYPE_ID, weaponType.getWeapon_type_id());
                return new PluginRouter("/Designer/WeaponType/AddPropertiesTable.jsp");
            } else {
                throw new WrongPageRequest("Тип оружия с таким id=" + weapon_type_id + " не существует. ");
            }
        } else {
            throw new WrongPageRequest("ID типа оружия не заданно.");
        }
    }

    /**
     * Метод,добавлящий свойств к типу оружия.
     * @param req Реквест.
     * @return PluginRouter c запрашиваемой страницей.
     * @throws DAOException Ошибка доступа к базе данных.
     * @throws WrongPageRequest Критическая ошибка в данных реквеста.
     */
    private PluginRouter addPropertiesToWeaponType(HttpServletRequest req) throws DAOException, WrongPageRequest {
        String weapon_type_id = req.getParameter(PluginConst.WEAPON_TYPE_ID);
        String[] properties_id = req.getParameterValues(PluginConst.PROPERTIES_ID);
        String error_message = "";
        if (weapon_type_id == null) {
            error_message = "ID типа оружия не задан.";
        }
        if ((properties_id == null) || (properties_id.length == 0)) {
            error_message = error_message + "Список включаемых атрибутов не может быть пустым.";
        }
        if (error_message.equals("")) {
            WeaponType weaponType = oracleDAOFactory.getWeaponTypesDAO().getById(new Integer(weapon_type_id));
            if (weaponType != null) {
                int lenght = properties_id.length;
                List<Weapon> listOfWeapon =
                        oracleDAOFactory.getWeaponDAO().getAllWeaponByWeaponType(weaponType.getWeapon_type_id());
                WeaponTypesPropertiesDAO wtpdao = oracleDAOFactory.getWeaponTypesPropertiesDAO();
                PropertyValueDAO pvdao = oracleDAOFactory.getPropertyValueDAO();
                Integer property_id = null;
                for (int i = 0; i < lenght; i++) {
                    property_id = new Integer(properties_id[i]);
                    wtpdao.create(new WeaponTypesProperties(property_id, weaponType.getWeapon_type_id()));
                    for (Weapon item : listOfWeapon) {
                        pvdao.create(new PropertyValue(property_id, "", item.getWeapon_id(), null));
                    }
                }
                return new PluginRouter("weapon-type-action.do"
                        + "?"
                        + PluginConst.SUBACTION
                        + "="
                        + PluginConst.GET_WEAPON_TYPE_PROPERTIES_LIST
                        + "&"
                        + PluginConst.WEAPON_TYPE_ID
                        + "="
                        + weapon_type_id, false);
            } else {
                throw new WrongPageRequest("Тип оружия с таким id=" + weapon_type_id + " не существует. ");
            }
        } else {
            throw new WrongPageRequest(error_message);
        }
    }
}
